#ifndef LEMC_SCROLLBAR_H
#define LEMC_SCROLLBAR_H

#include "guielement.h"
#include "button.h"
#include "../system/global.h"

class ScrollBar : public GuiElement
{
private:
	// The height of the slider.
	int m_slider_height;

	// The amount the value of the bar is changed when the up or down buttons are pressed.
	float m_step;

	// The distance of the slider to the border of the scrollbar.
	int m_slider_padding;

	// The background graphic of the part under the slider.
	std::string m_slider_background_graphic;

	// The graphic of the slider when it is not pressed.
	std::string m_slider_graphic_up;

	// The graphic of the slider when it is pressed.
	std::string m_slider_graphic_down;

	// The height of the up or down button (the width is not specified as a value because it is always the same as
	// the horizontal size.
	int m_button_height;

	// The graphic of the up-button, unpressed.
	std::string m_button_graphic_top_up;

	// The graphic of the up-button, pressed.
	std::string m_button_graphic_top_down;

	// The graphic of the down-button, unpressed.
	std::string m_button_graphic_bottom_up;

	// The graphic of the down-button, pressed.
	std::string m_button_graphic_bottom_down;

	// The top button.
	Button* m_top_button;

	// The bottom button.
	Button* m_bottom_button;

	// The value of the scrollbar. This is within the interval [0,1] where 0 is all the way to the top and 1 all the
	// way to the bottom. The value is changed when the slider is moved or the buttons are pressed, based on the
	// step attribute.
	float m_value;

	// The current position of the slider on the screen.
	int m_slider_position;

	// True if the mouse is currently holding the slider.
	bool m_grabbed;

	// The position on which the slider was grabbed.
	int m_grab_position;

	/*
	* Changes the value, which is only done by the buttons or the slider.
	*
	* @param value The new value to set. Must lie within [0,1].
	*/
	void ChangeValue(float value);

public:
	/*
	* Creates the scrollbar.
	*
	* @param id The id of the scrollbar, should be unique.
	* @param x The x position of the upper left corner of the scrollbar.
	* @param y The y position of the upper left corner of the scrollbar.
	* @param size_x Horizontal size of the scrollbar.
	* @param size_y Vertical size of the scrollbar.
	* @param button_height The height of the up and down buttons.
	* @param slider_padding The distance of the slider from the scrollbar borders.
	* @param slider_background_graphic The background graphic of the scrollbar.
	* @param slider_height The height of the slider.
	* @param slider_graphic_up The graphic of the slider, unpressed.
	* @param slider_graphic_down The graphic of the slider, pressed.
	* @param button_graphic_top_up The graphic of the top button, unpressed.
	* @param button_graphic_top_down The graphic of the top button, pressed.
	* @param button_graphic_bottom_up The graphic of the bottom button, unpressed.
	* @param button_graphic_bottom_down The graphic of the bottom button, pressed.
	*/
	ScrollBar(std::string id, int x, int y, int size_x, int size_y, float step = 0.0f,
		int button_height = STANDARD_SCROLLBAR_BUTTON_HEIGHT,
		int slider_padding = STANDARD_SCROLLBAR_SLIDER_PADDING,
		std::string slider_background_graphic = STANDARD_SCROLLBAR_SLIDER_BACKGROUND_GRAPHIC,
		int slider_height = STANDARD_SCROLLBAR_SLIDER_HEIGHT,
		std::string slider_graphic_up = STANDARD_SCROLLBAR_SLIDER_GRAPHIC_UP,
		std::string slider_graphic_down = STANDARD_SCROLLBAR_SLIDER_GRAPHIC_DOWN,
		std::string button_graphic_top_up = STANDARD_SCROLLBAR_TOP_BUTTON_GRAPHIC_UP, 
		std::string button_graphic_top_down = STANDARD_SCROLLBAR_TOP_BUTTON_GRAPHIC_DOWN,
		std::string button_graphic_bottom_up = STANDARD_SCROLLBAR_BOTTOM_BUTTON_GRAPHIC_UP,
		std::string button_graphic_bottom_down = STANDARD_SCROLLBAR_BOTTOM_BUTTON_GRAPHIC_DOWN);
	~ScrollBar();

	void ScrollToBottom();

	void PrimaryMouseButtonUp(int x, int y);
	void PrimaryMouseButtonDown(int x, int y);
	void MouseAxisChange(int x, int y);

	void Update();
	void Draw();

	void set_step (float step) { m_step = step; }
	float value() { return m_value; }
};

#endif